//
//  StatsViewController.m
//  FuelLog
//
//  Created by Pure Mass Communications on 9/1/08.
//  Copyright 2008 . All rights reserved.
//
//  Placed under GPL v2 with the kind permission of Pure Mass Communications
//
//  Modified to make compile under SDK 3.1 by Olaf Greck in May 2010
//
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.

//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.

//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

#import "StatsViewController.h"
#import "Plot.h"
#import "FuelLogAppDelegate.h"
#import "FuelLogViewController.h"
#import "Car.h"
#import "Gas.h"

@implementation StatsViewController

@synthesize beginDate, endDate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
	if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
		// Initialization code
		quartzView = nil;
		FuelLogAppDelegate *appDelegate = (FuelLogAppDelegate *)[[UIApplication sharedApplication] delegate];
		if (appDelegate.pumps.count > 0) {
			[self setBeginDate:((Gas *)[appDelegate.pumps objectAtIndex:0]).date];
			[self setEndDate:((Gas *)[appDelegate.pumps objectAtIndex:appDelegate.pumps.count - 1]).date];
		} else {
			[self setBeginDate:[FuelLogAppDelegate getNoonUTC:[NSDate date]]];
			[self setEndDate:[FuelLogAppDelegate getNoonUTC:[NSDate date]]];
		}
		[self setBoxes];
	}
	return self;
}

/*
- (void)loadView {
	[super loadView];
}
*/
 
/*
 If you need to do additional setup after loading the view, override viewDidLoad.
- (void)viewDidLoad {
}
 */

- (void)viewWillAppear:(BOOL)animated {
	[super viewWillAppear:animated];
	[self setBoxes];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
	// Return YES for supported orientations
	return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)didReceiveMemoryWarning {
	[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
	// Release anything that's not essential, such as cached data
}

- (void)dealloc {
	[beginDate release];
	[endDate release];
	[last10Button release];
	[last3mButton release];
	[last6mButton release];
	[last1yButton release];
	[allButton release];
	[beginDateButton release];
	[endDateButton release];
	[distanceLabel release];
	[fuelText release];
	[fuelLabel release];
	[dpfText release];
	[dpfLabel release];
	[costLabel release];
	[cpdLabel release];
	[cpdText release];
	[errorText release];
	[quartzView dealloc];
	[super dealloc];
}

- (IBAction)last10Click:(id)sender {
	[self setEndDate:[FuelLogAppDelegate getNoonUTC:[NSDate date]]];
	FuelLogAppDelegate *appDelegate = (FuelLogAppDelegate *)[[UIApplication sharedApplication] delegate];
	if ([appDelegate.pumps count] == 0) {
		[self setBeginDate:[FuelLogAppDelegate getNoonUTC:[NSDate date]]];
	} else {
		int count = 0, total = [appDelegate.pumps count];
		for (int i = 0; i < total; ++i) {
			Gas *gas = (Gas *)[appDelegate.pumps objectAtIndex:i];
			if (gas.full) ++count;
			if (count == 11) {
				[self setBeginDate:gas.date];
				break;
			}
		}
		if (count < 11) {
			[self setBeginDate:((Gas *)[appDelegate.pumps objectAtIndex:[appDelegate.pumps count]-1]).date];
		}
	}
	[self setBoxes];
}

- (IBAction)last3mClick:(id)sender {
	[self setEndDate:[FuelLogAppDelegate getNoonUTC:[NSDate date]]];
	[self setBeginDate:[FuelLogAppDelegate getMonthsBefore:endDate	months:3]];
	[self setBoxes];
}

- (IBAction)last6mClick:(id)sender {
	[self setEndDate:[FuelLogAppDelegate getNoonUTC:[NSDate date]]];
	[self setBeginDate:[FuelLogAppDelegate getMonthsBefore:endDate	months:6]];
	[self setBoxes];
}

- (IBAction)last1yClick:(id)sender {
	[self setEndDate:[FuelLogAppDelegate getNoonUTC:[NSDate date]]];
	[self setBeginDate:[FuelLogAppDelegate getMonthsBefore:endDate	months:12]];
	[self setBoxes];
}

- (IBAction)allClick:(id)sender {
	[self setEndDate:[FuelLogAppDelegate getNoonUTC:[NSDate date]]];
	FuelLogAppDelegate *appDelegate = (FuelLogAppDelegate *)[[UIApplication sharedApplication] delegate];
	if ([appDelegate.pumps count] == 0) {
		[self setBeginDate:[FuelLogAppDelegate getNoonUTC:[NSDate date]]];
	} else {
		[self setBeginDate:((Gas *)[appDelegate.pumps objectAtIndex:[appDelegate.pumps count]-1]).date];
	}
	[self setBoxes];
}

- (IBAction)selectBeginDate:(id)sender {
	DateViewController *dateController = [FuelLogViewController dateViewController];
	[dateController setEditedObject:self];
	[dateController setEditedFieldKey:@"beginDate"];
	[dateController setText:@"Begin date"];
	[dateController setDateValue:beginDate];
	[self presentModalViewController:dateController animated:YES];
}

- (IBAction)selectEndDate:(id)sender {
	DateViewController *dateController = [FuelLogViewController dateViewController];
	[dateController setEditedObject:self];
	[dateController setEditedFieldKey:@"endDate"];
	[dateController setText:@"End date"];
	[dateController setDateValue:endDate];
	[self presentModalViewController:dateController animated:YES];
}

- (IBAction)done:(id)sender {
	[errorText setText:@""];
	[self dismissModalViewControllerAnimated:YES];
}

- (void)setBoxes {
	FuelLogAppDelegate *appDelegate = (FuelLogAppDelegate *)[[UIApplication sharedApplication] delegate];
	[distanceText setText:[FuelLogAppDelegate pref].distanceText];
	[fuelText setText:[FuelLogAppDelegate pref].fuelText];
	[dpfText setText:[FuelLogAppDelegate pref].dpfText];
	[cpdText setText:[FuelLogAppDelegate pref].cpdText];
	
	if (appDelegate.currentCar) {
		[carLabel setText:appDelegate.currentCar.label];
	}
	NSDateFormatter *formatter = [FuelLogAppDelegate pref].dateFormatter;
	if (endDate == [endDate earlierDate:beginDate]) {
		NSDate *temp = endDate;
		endDate = beginDate;
		beginDate = temp;
	}
	NSString *beginTitle = [formatter stringFromDate:beginDate];
	[beginDateButton setTitle:beginTitle forState:UIControlStateNormal];
	[beginDateButton setTitle:beginTitle forState:UIControlStateHighlighted];
	[beginDateButton setTitle:beginTitle forState:UIControlStateSelected];
	NSString *endTitle = [formatter stringFromDate:endDate];
	[endDateButton setTitle:endTitle forState:UIControlStateNormal];
	[endDateButton setTitle:endTitle forState:UIControlStateHighlighted];
	[endDateButton setTitle:endTitle forState:UIControlStateSelected];
	
	int beginIdx, endIdx, fillCount = 0;
	float totalDistance = 0.0, totalFuel = 0.0, totalCost = 0.0, dpf = 0.0, cpd = 0.0;
	for (beginIdx = appDelegate.pumps.count - 1; beginIdx >= 0; --beginIdx) {
		Gas *gas = (Gas *)[appDelegate.pumps objectAtIndex:beginIdx];
		NSComparisonResult comp = [beginDate compare:gas.date];
		if (comp == NSOrderedSame || comp == NSOrderedAscending) break;
	}
	for (endIdx = 0; endIdx < appDelegate.pumps.count; ++endIdx) {
		Gas *gas = (Gas *)[appDelegate.pumps objectAtIndex:endIdx];
		NSComparisonResult comp = [endDate compare:gas.date];
		if (comp == NSOrderedSame || comp == NSOrderedDescending) break;
	}
	if (beginIdx < 0 || endIdx == appDelegate.pumps.count || endIdx >= beginIdx) {
		[errorText setText:@"There are no fill-ups between the selected dates."];
		goto error;
	}
	Gas *beginGas = (Gas *)[appDelegate.pumps objectAtIndex:beginIdx];
	Gas *endGas = (Gas *)[appDelegate.pumps objectAtIndex:endIdx];
	if (beginGas.odometer >= endGas.odometer) {
		[errorText setText:@"The car had not been driven between the selected dates."];
		goto error;
	}
	totalDistance = endGas.odometer - beginGas.odometer;
	int firstFillIdx = -1, lastFillIdx = -1;
	for (int i = beginIdx; i >= endIdx; --i) {
		Gas *gas = (Gas *)[appDelegate.pumps objectAtIndex:i];
		if (gas.full) {
			fillCount++;
			lastFillIdx = i;
			if (firstFillIdx == -1) {
				firstFillIdx = i;
			}
		}
		totalFuel += gas.volume;
		totalCost += gas.cost;
	}

	float fuelDenom = 0.0, costNumer = 0.0, distanceStat = 0.0;
	Gas *firstFillGas = (Gas *)[appDelegate.pumps objectAtIndex:firstFillIdx];
	Gas *lastFillGas = (Gas *)[appDelegate.pumps objectAtIndex:lastFillIdx];
	distanceStat = lastFillGas.odometer - firstFillGas.odometer;
	if (fillCount > 1 && distanceStat >= 0.0) {
		for (int i = firstFillIdx - 1; i >= lastFillIdx; --i) {
			Gas *gas = (Gas *)[appDelegate.pumps objectAtIndex:i];
			fuelDenom += gas.volume;
			costNumer += gas.cost;
		}
	}
	
	if (fuelDenom > 0) {
		dpf = distanceStat / fuelDenom;
		int prefUnits = [FuelLogAppDelegate pref].units;
		if (dpf > 0.0 && prefUnits == INV_METRIC) {
			dpf = 100.0 / dpf;
		} else if (dpf > 0.0 && prefUnits == NORWAY) {
			dpf = 10.0 / dpf;
		} else if ([FuelLogAppDelegate pref].units == UK) {
			dpf = dpf * UK_GALLON;
		}
	}
	if (distanceStat > 0) cpd = costNumer / distanceStat;
	[distanceLabel setText:[[FuelLogAppDelegate pref].distanceFormatter stringFromNumber:[NSNumber numberWithFloat:totalDistance]]];
	NSString *fuel = [[FuelLogAppDelegate pref].volumeFormatter stringFromNumber:[NSNumber numberWithFloat:totalFuel]];
	if (NO && [FuelLogAppDelegate pref].units == UK) {
		NSString *fuelConverted = [[FuelLogAppDelegate pref].volumeFormatter stringFromNumber:[NSNumber numberWithFloat:totalFuel*UK_GALLON]];
		[fuelLabel setText:[NSString stringWithFormat:@"%@ (%@G)", fuel, fuelConverted]];
	} else {
		[fuelLabel setText:fuel];
	}
	[dpfLabel setText:[[FuelLogAppDelegate pref].volumeFormatter stringFromNumber:[NSNumber numberWithFloat:dpf]]];
	[costLabel setText:[[FuelLogAppDelegate pref].costFormatter stringFromNumber:[NSNumber numberWithFloat:totalCost]]];
	[cpdLabel setText:[[FuelLogAppDelegate pref].costFormatter stringFromNumber:[NSNumber numberWithFloat:cpd]]];

	if (fillCount < 3) {
		[errorText setText:@"3 or more full-tanks are needed to plot fuel efficiency."];
		goto noplot;
	} else {
		[errorText setText:@""];
		CGRect rect = CGRectMake(20.0, 270.0, 280.0, 175.0);
		if (quartzView && quartzView.superview) {
			[quartzView removeFromSuperview];
			[quartzView.delegate release];
			[quartzView release];
			quartzView = nil;
		}
		quartzView = [[QuartzView alloc] initWithFrame:rect];
		Plot *plot = [Plot alloc];
		plot.beginIdx = beginIdx;
		plot.endIdx = endIdx;
		quartzView.delegate = plot;
		[self.view addSubview:quartzView];
	}
	return;

error:
	if (quartzView) {
		[quartzView removeFromSuperview];
		[quartzView.delegate release];
		[quartzView release];
		quartzView = nil;
	}
	[self.view setNeedsDisplayInRect:CGRectMake(20.0, 270.0, 280.0, 175.0)];
	[distanceLabel setText:[[FuelLogAppDelegate pref].distanceFormatter stringFromNumber:[NSNumber numberWithFloat:0.0]]];
	[fuelLabel setText:[[FuelLogAppDelegate pref].volumeFormatter stringFromNumber:[NSNumber numberWithFloat:0.0]]];
	[dpfLabel setText:[[FuelLogAppDelegate pref].volumeFormatter stringFromNumber:[NSNumber numberWithFloat:0.0]]];
	[costLabel setText:[[FuelLogAppDelegate pref].costFormatter stringFromNumber:[NSNumber numberWithFloat:0.0]]];
	[cpdLabel setText:[[FuelLogAppDelegate pref].costFormatter stringFromNumber:[NSNumber numberWithFloat:0.0]]];
	return;
	
noplot:
	if (quartzView) {
		[quartzView removeFromSuperview];
		[quartzView.delegate release];
		[quartzView release];
		quartzView = nil;
	}
	return;
}

@end
